<?php
namespace app\common\loader;

class Base {
    private static $instances = [];
    private static $anyInstances = [];
    private static $module = 'common';

    public static function getInstance($name = '') {
        if($name == '') {
            $name = 'Loader';
        }
        if(isset(static::$instances[$name])) {
            return static::$instances[$name];
        }
        $class = str_replace('Base', $name, static::class);

        if(class_exists($class)) {
            static::$instances[$name] = new $class();
        } else {
            static::$instances[$name] = new Mock($name);
        }
        return static::$instances[$name];
    }

	// 魔术方法，当调用对象不存在的方法时会触发
    public function __call($method, $arguments) {
        // 检查类中是否存在该静态方法
        if (method_exists($this, $method)) {
            // 调用类的静态方法
            return call_user_func_array([__CLASS__, $method], $arguments);
        }
        // 如果静态方法也不存在，抛出异常或进行其他处理
        throw new BadMethodCallException("Method $method does not exist.");
    }

    public static function get_base() {
        return 'app\\' . static::$module;
    }

    //把模块名传给event
    public static function filter_event_args($args) {
        array_unshift($args, static::$module);
        return $args;
    }

    //地址生成any
    public static function classAny($any, $name) {
        if(strpos($name, 'app\\') === false) {
            $name = static::get_base() . '\\' . $any . '\\' . $name;
        }
        return $name;
    }

    //生成any类地址
    public static function loadAny($any, $name = null, $args = []) {
        if($name === null) {
            $name = 'Index';
        }
        if(isset(static::$instances[$any])) {
            if(isset(static::$instances[$any][$name])) {
                return static::$instances[$any][$name];
            }
        } else {
            static::$instances[$any] = [];
        }
        $classname = static::classAny($any, $name);
        if (!class_exists($classname)) {
            if(static::$module != 'common') {
                return loader()->loadAny($any, $name);
            } else {
                return null;
            }
        }
        $filterFun = 'filter_' . $name . '_args';
        if(method_exists(static::class, $filterFun)) {
            $args = static::$filterFun($args);
        }
        $obj = new $classname(...$args);
        static::$instances[$any][$name] = $obj;
        return $obj;
    }

    //生成模型类地址
    public static function classModel($name) {
        if(strpos($name, 'app\\') === false) {
            $name = static::get_base() . '\\model\\' . $name;
        }
        return $name;
    }

    //加载模型
    public static function loadModel($name) {
        $name = static::classModel($name);
        return static::loadAny('model', $name);
    }

    //生成验证器类地址
    public static function classValidate($name) {
        if(strpos($name, 'app\\') === false) {
            $name = static::get_base() . '\\validate\\' . $name;
        }
        return $name;
    }

    //加载验证器
    public static function loadValidate($name, $args = []) {
        return static::loadAny('validate', $name, $args);
    }

    //生成工具类地址
    public static function classTool($name) {
        if(strpos($name, 'app\\') === false) {
            $name = static::get_base() . '\\tool\\' . $name;
        }
        return $name;
    }

    //加载工具类
    public static function loadTool($name, $args = []) {
        return static::loadAny('tool', $name, $args);
    }

    //生成流程地址
    public static function classProcess($name) {
        if(strpos($name, 'app\\') === false) {
            $name = static::get_base() . '\\process\\' . $name;
        }
        return $name;
    }

    //加载流程类
    public static function loadProcess($name, $args = []) {
        return static::loadAny('process', $name, $args);
    }

    //生成枚举地址
    public static function classEnum($name) {
        if(strpos($name, 'app\\') === false) {
            $name = static::get_base() . '\\enum\\' . $name;
        }
        return $name;
    }

    //加载枚举类
    public static function loadEnum($name, $args = []) {
        return static::loadAny('enum', $name, $args);
    }

    //生成存储地址
    public static function classStorage($name) {
        if(strpos($name, 'app\\') === false) {
            $name = static::get_base() . '\\storage\\' . $name;
        }
        return $name;
    }

    //加载存储类
    public static function loadStorage($name, $args = []) {
        return static::loadAny('storage', $name, $args);
    }

    //生成单执地址
    public static function classOnly($name) {
        if(strpos($name, 'app\\') === false) {
            $name = static::get_base() . '\\only\\' . $name;
        }
        return $name;
    }

    //加载单执类
    public static function loadOnly($name, $args = []) {
        return static::loadAny('only', $name, $args);
    }
}
